#ifndef _SKILLBASE_H
#define  _SKILLBASE_H

#include "Common/Utility/ServerTime.h"
#include "base/core/os/time.h"
#include "Common/ComTypeDefine.h"
#include "Common/CharacterDefine.h"
#include "SkillCommonDef.h"
class SkillPart;
enum SkillFightType
{
	SkillFightType_SkillBase = 1,
	SkillFightType_SkillBullet = 2,
	SkillFightType_SkillShadowStrike = 3,
	SkillFightType_SkillFlash = 4,
	SkillFightType_SkillSummon = 5,
	SkillFightType_SkillTuXi = 6,
	SkillFightType_Collide = 7, //冲撞
	SkillFightType_Gouzi = 8,	//钩子
	SKillFightType_Relive = 9,	//复活
	SkillFightType_SomeSummon = 10, //招多个招换物
	SkillFightType_MoveAOE = 17,			//移动AOE，根据速度，算出查找目标区域
	SkillFightType_SomeBulletOnePoint	= 18,	//多个弹道，一个点的aoe技能
	SkillFightType_SomePointDelayAoe	= 19,	//多点延时aoe
	SkillFightType_ShareDamegeSkill		= 20,	//分担伤害技能
	SkillFightType_LockSomeTarget = 21,	//锁定指定次数的攻击，如果人数够，一人一次，如果人数不够，有人有多次，保证受伤次数是够的
};

enum SkillSummonType
{
	SkillSummonType_SkillSomeSummon =4,	//技能招换多个招换物 
};


enum enSkillSaveType
{
	enSkillSaveType_SaveDB = 1,	//存盘的
	enSkillSaveType_Online = 2,	//上线一直存在的
	enSkillSaveType_UseOnce = 3,	//仅使用一次的
};

typedef std::list<CharIDType> cList;
//技能存盘基本信息
struct stSkillInfo 
{
	stSkillInfo()
	{
		_Id=0;   //配置ID
		_level=0;
		_cdTimeStamps=0;    //cd时间点
		_priority=0;		//优先级,给怪物AI的技能池用  普通 技能优先级 0
		_pSkillmeta=nullptr;
		_posSummon = Point3<float>(0.0, 0.0, 0.0);
		_isUnLock = false;
		_fightValue = 0;
		_vRelatedSkill.clear();
		_enSaveType = enSkillSaveType_Online;
	}
	~stSkillInfo()
	{
		_Id=0;   //配置ID
		_level=0;
		_cdTimeStamps=0;    //cd时间点
		_priority=0;		//优先级,给怪物AI的技能池用  普通 技能优先级 0
		_pSkillmeta=NULL;
		_posSummon = Point3<float>(0.0, 0.0, 0.0);
		_isUnLock = false;
		_vRelatedSkill.clear();
		_fightValue = 0;
		_enSaveType = enSkillSaveType_Online;
	}
	//获取技能CD时间
	int64_t GetLeftCDTime() const
	{
		if (!_pSkillmeta)
		{
			return 0;
		}
		int64_t leftTime = _pSkillmeta->cd- (Time::Now().UnixMSec() - _cdTimeStamps);
		leftTime = leftTime > 0 ? leftTime : 0;

		return  leftTime;
	}

	//获取技能CD时间
	int64_t GetAILeftCDTime() const
	{
		if (!_pSkillmeta)
		{
			return 0;
		}
		int64_t leftTime = _pSkillmeta->cd  - (Time::Now().UnixMSec() - _cdTimeStamps);
		leftTime = leftTime > 0 ? leftTime : 0;

		return  leftTime;
	}

	bool IsSameSkill(uint32_t skillID)
	{
		if (skillID==_Id)
		{
			return true;
		}

		for (int i = 0; i < (int)_vRelatedSkill.size();++i)
		{
			if (_vRelatedSkill[i]==skillID)
			{
				return true;
			}
		}
		return false;
	}

	uint32_t					_Id;   //配置ID
	uint32_t					_level;
	uint64_t					_cdTimeStamps;    //cd时间点
	uint32_t					_priority;		//优先级,给怪物AI的技能池用  普通 技能优先级 0
	uint32_t					_cdPercent;		//减CD百分比
	const SkillCfg*				_pSkillmeta;
	Point3<float> 				_posSummon;  //招换物位置
	bool						_isUnLock;	 //是否解锁
	std::vector<uint32_t>       _vRelatedSkill; //关联技能
	float					   _fightValue;	//战斗力
	enSkillSaveType			   _enSaveType;		//标记是否需要存盘buff，现在这里技能有，主动（人物身上的，人物由物品加的，或者由其它途径加进来的），被动，只有人物身上的要存盘
};

//技能战斗信息
class SkillBase
{
protected:
	typedef void(SkillBase::*pTimedoFunc)(uint32_t);
	typedef std::unordered_map<uint32_t, pTimedoFunc> mapTimedoFunc;

	SkillFightType m_enType;    
	uint32_t m_nGlobelID;		//技能战斗信息唯一ID
	uint32_t m_nID;				//技能的配置表ID，这里不是该对像的唯一ID
	uint32_t m_focoTime;		//冷却时间
	Point3<float> m_targetPos;  //目标点
	uint8_t m_curState;			
	uint32_t m_curDamageCount;	//当前生效点
	
	vector<CharIDType> m_vTargetCids;  //目标列表

	mapTimedoFunc m_mapTimedofunc;
	SkillPart * m_pPart;
	Point3<float>				m_skillDir;		//技能方向，一般情况是和人物方向一致，特殊技能人物行走后，不一样

	//连招用----------
	uint32_t				 m_nStep;  //技能连招阶段
	uint32_t				m_nStopStep;	//打断连招阶段
	VEC_UINT32				m_vSkillId;	//连招技能ID数组
	Point3<float>		m_masterPos;    //这里记录放技能时的位置
	//----------下面是给BUf用的一些信息
	//Point3<float>				m_posSummon;		//招换物位置信息
	
public:
	SkillBase();
	virtual ~SkillBase();
public:
	virtual bool Init(SkillFightType Type, const SkillCfg* pConfig, uint32_t globelID, SkillPart * pPart);
	virtual uint32_t GetSkillID();
	virtual bool IsSameSkill(uint32_t skillID);
	uint32_t GetGlobelID();
	Point3<float> GetSkillDir();
	void SetSkillDir(Point3<float> dir);
	virtual void SetTargetPos(Point3<float> targetPos);
	virtual Point3<float> & GetTargetPos();
	
	virtual void SetTargetCidsList(vector<CharIDType> vtargetList);
	virtual vector<CharIDType> & GetTargetList();
	void SetStopStep(uint32_t  step);

	//有些怪物使用的技能，在释放之前，需要先找多个目标点，以前一个点由AI传入，现在暂时放该类技能中处理
	virtual void GetTargetMutPos(std::vector<Point3<float> > & vPos){};
	//技能延时时间后的处理
	virtual void ReadyState(uint32_t skillId);
	virtual void DamageState(uint32_t skillId);


	virtual void OnNextSkillState(uint32_t skillId);

	virtual void OnReadyTimedo(uint32_t skillId);
	virtual void OnFly(uint32_t skillId);
	virtual void OnDamageTimedo(uint32_t skillId);
	//主要给玩家用，玩家放技能是客户端传过来的目标
	virtual void OnDamageTimedoPlayer(uint32_t skillId,cList & vtargetList);
	virtual void OnNextSkillStatedo(uint32_t skillId);

	Point3<float> GetMasterPos(){ return m_masterPos; };
	SkillFightType GetSkillFightType(){ return m_enType; }
	//根据起点，方向，间隔时间，算出目标应在的终点坐标和方向
	void GetDesPos(Point3<float> startPos, Point3<float> startDir,uint32_t nSpeed, Point3<float> & desPos, uint32_t intervalTime);

	virtual void OnTime();

	virtual uint32_t GetDamageTime();
	virtual uint32_t GetFocoTime();

	virtual void refreshData();
	//void SetSummonPos(Point3<float>pos){ m_posSummon = pos; };

	//Point3<float>& GetSummonPos(){ return m_posSummon; };
};



#endif
